/**
 * 数组的构造器有哪几种？
 * 哪些是改变自身的方法？
 * 哪些是不改变自身的方法？
 * 遍历的方法有哪些？
 * */
// 截至ES7数组的标准方法有33个和一个非标准方法
/**
 * 数组的创建有构造器 new Array 和 对象字面量的方式
 * 数组的构造器
 * 1、var arr1 = new Array(1,2,3,4)   => [1,2,3,4]
 * 2、var arr2 = new Array(6) ===>[ <6 empty items> ]长度为6的空数组
 * 3、new Array(arg1, arg2,…)，参数长度为 0 或长度大于等于 2 时，传入的参数将按照顺序依次成为新数组的第 0 至第 N 项（参数长度为 0 时，返回空数组）；
 * 4、new Array(len)，当 len 不是数值时，处理同上，返回一个只包含 len 元素一项的数组；当 len 为数值时，len 最大不能超过 32 位无符号整型，即需要小于 2 的 32 次方（len 最大为 Math.pow(2,32)），否则将抛出 RangeError。
 * 5、ES6新增的Array.of和ES6.from
 * 6、Array.of和 new Array 类似唯一区别是单个参数为数值的时候 new Array 会变为长度为数值的空数组。Array.of会变为[数值]的数组
 * 7、array.from有三个参数 类似数组的对象，必选；加工函数，新生成的数组会经过该函数的加工再返回； this 作用域，表示加工函数执行时 this 的值。
 *  obj 对象以外，拥有迭代器的对象还包括 String、Set、Map 等，Array.from都可以使用 
 * 
 * 
 *  */ 

// console.log(Array.of(8),new Array(8)) // [ 8 ] [ <8 empty items> ] 

var obj = {0: 'a', 1: 'b', 2:'c', length: 3};
var arr = Array.from(obj, function(value, index){
//   console.log(value, index, this, arguments.length);
//   return value.repeat(1);   //必须指定返回值，否则返回 undefi ned,repeat是重复的次数
}, obj);
// console.log(arr)

// 数组判断
let a = []
// console.log(a.constructor)   [Function: Array]
// console.log(a instanceof Array)       // 1.基于instanceof  true
// console.log(a.constructor === Array)  // 2.基于constructor true
// console.log(Array.prototype.isPrototypeOf(a))  // 3.基于Object.prototype.isPrototypeOf true

// console.log(Object.getPrototypeOf(a) === Array.prototype) // 4.基于getPrototypeOf true
 
// console.log(Object.prototype.toString.apply(a) === '[object Array]') // 5.基于Object.prototype.toString  true

// ES6出现了 Array.isArray方法
// isArray的polyfill 方法
if(!Array.isArray){
    Array.isArray = function(arg){ 
        return Object.prototype.toString.apply(arg) === '[object Array]'
    }
}
// console.log(Array.isArray(a)) // true

// 数组改变自身的方法9个：pop push shift unshift sort reverse splice 以及ES6新增的copyWithin、fill
// 不改变自身的方法11个：concat join slice toString toLocaleString indexOf lastIndexOf 未形成标准的toSource 以及ES7的includes，valueOf, at
// 数组的遍历方法14个：forEach every some filter map reduce reduceRight 以及es6新增的entries、find、findIndex、keys、values, flat,flatMap

// 改变自身的方法-----------------------------------------
// pop push shift unshift sort reverse splice 以及ES6新增的copyWithin、fill
// var arr = [1,2,3,4]
// console.log(arr.pop(),arr)     // 4 [1,2,3] pop()方法后返回的是删除的结尾的具体值，原数组变为删除结尾的新数组 
// console.log(arr.push(5),arr)   // 5 [1,2,3,4,5] push(XX)向数组的末尾添加一个或更多元素，并返回新的长度，原数组变为结尾增加XX后的新数组 
// console.log(arr.shift(),arr)   // 1 [2,3,4] shift()方法后返回的是删除开头的具体值，原数组变为删除第一项的新数组
// console.log(arr.unshift(0),arr)   // 5 [0,1,2,3,4] unshift(XXX)向数组的开头添加一个或更多元素，并返回新的长度。原数组变为开头增加XXX后的新数组
// console.log(arr.reverse(),arr)  // [ 4, 3, 2, 1 ] [ 4, 3, 2, 1 ] 反转数组的元素顺序。原数组就是返回的值
// console.log(arr.splice(0,2,[1,2,3]),arr)      //[ 1, 2 ] [ [ 1, 2, 3 ], 3, 4 ] 从数组中添加或删除元素，splice(index，XXX,oooo)返回时的是从index的位置开始，操作的长度为XXX,新增的数据为oooo
// console.log(arr.at(2),arr) // 3 [ 1, 2, 3, 4 ]

// var arr = [1,2,3,4,0,11]
// console.log(arr.sort(),arr)    // [ 0, 1, 11, 2, 3, 4 ] [ 0, 1, 11, 2, 3, 4 ] 对数组的元素进行排序。

// var arr1 = ['holle','world','haha']
// console.log(arr1.copyWithin(1,0,1),arr1) //[ 'holle', 'holle', 'haha' ] [ 'holle', 'holle', 'haha' ] 从数组的指定位置拷贝元素到数组的另一个指定位置中copyWithin(target,start,end)  target必需。复制到指定目标索引位置。start可选。元素复制的起始位置。end可选。停止复制的索引位置 (默认为 array.length)。如果为负值，表示倒数。 

// var arr2 = ['hello','heihei','hahaha','hengheng']
// console.log(arr2.fill(8,0,2)) // [ 8, 8, 'hahaha', 'hengheng' ] 用于将一个固定值替换数组的元素 fill(value,start,end) value必需。填充的值。start可选。开始填充位置。end可选。停止填充位置 (默认为 array.length)
// 

/**
 * 给你两个有序整数数组 nums1 和 nums2，请你将 nums2 合并到 nums1 中，使 nums1 成为一个有序数组。
 * 输入:
 * nums1 = [1,2,3,0,0,0]； m = 3
 * nums2 = [2,5,6]；       n = 3
 * 输出: [1,2,2,3,5,6]
*/
// var nums1 = [1,2,3,0,0,0], nums2 = [2,5,6];
// function merge(nums1,m,nums2,n){
//     nums1.splice(m)
//     nums2.splice(n)
//     nums1.push(...nums2)
//     nums1.sort((a,b)=>a-b)
//     return nums1
// }
// console.log(merge(nums1,3,nums2,3))


// 不改变自身的方法 14---------------------------------------
// concat join slice toString toLocaleString indexOf lastIndexOf 未形成标准的toSource 以及ES7的includes,valueOf
// var arrNo = [1, 2, 3, 4]

// console.log([5,6].concat(arrNo,arrNo),arrNo)   // [5, 6, 1, 2, 3,4, 1, 2, 3, 4 ] [ 1, 2, 3, 4 ]	连接两个或更多的数组，并返回结果。
// console.log( arrNo.join('-')) // 1-2-3-4 把数组中的所有元素转换为一个字符串join(XX) 使用XX 作为=分隔符
// console.log(arrNo.slice(1,3),arrNo) // [ 2, 3 ] [ 1, 2, 3, 4 ] 选取数组的一部分，并返回一个新数组 slice(start,end)
// console.log(arrNo.toString(),arrNo) // 1,2,3,4 [ 1, 2, 3, 4 ] 把数组转换为字符串，并返回结果
// console.log(arrNo.indexOf(1,2),arrNo)  // -1 [ 1, 2, 3, 4 ] 可返回数组中某个指定的元素位置。 item必须。查找的元素。start可选的整数参数。规定在数组中开始检索的位置。它的合法取值是 0 到 stringObject.length - 1。如省略该参数，则将从字符串的首字符开始检索。
// console.log(arrNo.lastIndexOf(2),arrNo)   //  1 [ 1, 2, 3, 4 ] 返回一个指定的元素在数组中最后出现的位置，从该字符串的后面向前查找；参数和indexOf 一样
// console.log(arrNo.includes(2))   // true 判断一个数组是否包含一个指定的值
// console.log(arrNo.valueOf()) // 返回数组的原始值[1, 2, 3, 4]

// var array= [{name:'zz'}, 123, "abc", new Date()]
// console.log(array.toLocaleString(),array)  // [object Object],123,abc,2023/8/29 10:36:50 [ { name: 'zz' }, 123, 'abc', 2023-08-29T02:36:50.665Z ]


// 数组的遍历方法14个--------------------------------------------------
// forEach every some filter map reduce reduceRight 以及es6新增的entries、find、findIndex、keys、values,flat,flatMap
// var arrList = [1,2,3,4,5]
// var newForEachArr = arrList.forEach((item)=>{
//     console.log(item) // 1 2 3 4 5
// })
// console.log(arrList,newForEachArr) // [ 1, 2, 3, 4, 5 ] undefined   数组每个元素都执行一次回调函数。没有返回值

// var newArr1 =arrList.every(item=>item>4) console.log(newArr1,arrList) // false [ 1, 2, 3, 4, 5 ] 检测数值元素的每个元素是否都符合条件 返回一个布尔值
// var newArr2 = arrList.some(item=> item>4); console.log(newArr2, arrList) // true [ 1, 2, 3, 4, 5 ] 检测数组元素中是否有元素符合指定条件。 返回一个布尔值
// var newArr3 = arrList.filter(item=>item>3) ;console.log(newArr3,arrList) // [ 4, 5 ] [ 1, 2, 3, 4, 5 ] 检测数值元素，并返回符合条件所有元素的数组
// var newArr4 = arrList.map(item=>item + 1); console.log(newArr4,arrList) // [ 2, 3, 4, 5, 6 ] [ 1, 2, 3, 4, 5 ] 通过指定函数处理数组的每个元素，并返回处理后的数组
// var newArr5 = arrList.entries(); console.log(newArr5, arrList)
// var newArr6 = arrList.find((item)=>{return item>0}); console.log(arrList,newArr6) // [ 1, 2, 3, 4, 5 ] 1 find()方法返回通过测试（函数内判断）的数组的第一个元素的值
// var newArr7 = arrList.findIndex(item=>item>3); console.log(arrList,newArr7) // [ 1, 2, 3, 4, 5 ] 3 findIndex()方法返回通过测试（函数内判断）的数组的第一个元素的index
// var newArr8 = arrList.keys();  console.log([...newArr8],newArr8, arrList) //[ 0, 1, 2, 3, 4 ] Object [Array Iterator] {} [ 1, 2, 3, 4, 5 ] keys() 方法用于从数组创建一个包含数组键的可迭代对象
// console.log("2123".keys())  //"2123".keys is not a function
// var nweArr9 = arrList.values(); console.log([...nweArr9],nweArr9,arrList,) // [ 1, 2, 3, 4, 5 ] Object [Array Iterator] {} [ 1, 2, 3, 4, 5 ]

// var arrList2 = [1,2,3,[4,5,[6]]]
// var newArr10 = arrList2.flat(); console.log(newArr10, arrList2) // [ 1, 2, 3, 4, 5, [ 6 ] ] [ 1, 2, 3, [ 4, 5, [ 6 ] ] ]
// var newArr10 = arrList2.flat(2);console.log(newArr10, arrList2) // [ 1, 2, 3, 4, 5, 6 ] [ 1, 2, 3, [ 4, 5, [ 6 ] ] ]  flat() 方法方法会按照一个可指定的深度递归遍历数组，并将所有元素与遍历到的子数组中的元素合并为一个新数组返回 参数：指定要提取嵌套数组的结构深度，默认值为 1
/**
 * reduce((total, currentValue, currentIndex, arr)=>{},initialValue)
 * reduceRight((total, currentValue, currentIndex, arr)=>{},initialValue)
 * total	必需。初始值, 或者计算结束后的返回值。
 * currentValue	必需。当前元素
 * currentIndex	可选。当前元素的索引
 * arr	可选。当前元素所属的数组对象。
 * initialValue	可选。传递给函数的初始值
 * */ 

/**
 * 题目：var arr = [{name:"one"},{name:"two"},{name:"three"}] 变为 one,two&three
*/

// var arr = [{ name: "one" }, { name: "two" }, { name: "three" }]

// var newarr = arr.reduce(function(prev,current,index,array){
//     console.log(prev, '-----',current,'000000')
//     if(index === 0){
//         return current.name
//     } else if (index === array.length - 1){
//         return prev + "&" + current.name
//     }else{
//         return prev + "," +current.name
//     }
// },'')

// console.log(newarr,'---')
